package model

import (
	"context"
	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/frame/g"
	v1 "goAdminV1/api/user/v1"
	"goAdminV1/internal/dao"
	"goAdminV1/internal/model/do"
	"goAdminV1/internal/model/entity"
	"strconv"
)

// GetUserByUsername 根据用户名查询用户信息
func GetUserByUsername(ctx context.Context, username string) (*entity.CaUsers, error) {
	var user *entity.CaUsers
	// 使用 GoFrame 的 ORM 查询用户信息
	err := dao.CaUsers.Ctx(ctx).Where("email", username).Scan(&user)
	if err != nil {
		return nil, err
	}
	return user, nil
}

// ExistsByUsername 检查用户名是否存在
func ExistsByUsername(ctx context.Context, username string) (bool, error) {
	count, err := dao.CaUsers.Ctx(ctx).Where("username", username).Count()
	if err != nil {
		return false, err
	}
	return count > 0, nil
}

// CreateUser 插入用户数据
func CreateUser(ctx context.Context, user entity.CaUsers) (int, error) {
	result, err := dao.CaUsers.Ctx(ctx).Data(user).Insert()
	if err != nil {
		return 0, err
	}
	userId, err := result.LastInsertId()
	return int(userId), err
}

// InsertUserRoles 插入用户角色关联数据
func InsertUserRoles(ctx context.Context, userId int, roles []int) error {
	roleData := make([]g.Map, len(roles))
	for i, roleId := range roles {
		roleData[i] = g.Map{"user_id": userId, "role_id": roleId}
	}
	_, err := dao.CaUserHasRoles.Ctx(ctx).Data(roleData).Insert()
	return err
}

// InsertUserJobs 插入用户岗位关联数据
func InsertUserJobs(ctx context.Context, userId int, jobs []int) error {
	jobData := make([]g.Map, len(jobs))
	for i, jobId := range jobs {
		jobData[i] = g.Map{"user_id": userId, "job_id": jobId}
	}
	_, err := dao.CaUserHasJobs.Ctx(ctx).Data(jobData).Insert()
	return err
}

// GetUserById 根据用户 Id 查询用户信息
func GetUserById(ctx context.Context, id int) (*entity.CaUsers, error) {
	var user entity.CaUsers
	err := dao.CaUsers.Ctx(ctx).Where("id", id).Scan(&user)
	if err != nil {
		return nil, err
	}
	if user.Id == 0 {
		return nil, nil // 用户不存在
	}
	return &user, nil
}

// UpdateUser 根据用户 Id 更新用户信息
func UpdateUser(ctx context.Context, id int, data map[string]interface{}) error {
	_, err := dao.CaUsers.Ctx(ctx).Where("id", id).Data(data).Update()
	return err
}

// DeleteUserRoles 删除用户角色关联
func DeleteUserRoles(ctx context.Context, userId int) error {
	_, err := dao.CaUserHasRoles.Ctx(ctx).Where("user_id", userId).Delete()
	return err
}

// DeleteUserJobs 删除用户岗位关联
func DeleteUserJobs(ctx context.Context, userId int) error {
	_, err := dao.CaUserHasJobs.Ctx(ctx).Where("user_id", userId).Delete()
	return err
}

// DeleteUserById 根据用户 Id 删除用户
func DeleteUserById(ctx context.Context, id string) error {
	_, err := dao.CaUsers.Ctx(ctx).Where("id", id).Delete()
	if err != nil {
		return err
	}
	return nil
}

func GetUserOnlineByID(ctx context.Context, userID uint) (*do.CaUsers, []v1.Permission, error) {
	// 查询用户信息
	var userData do.CaUsers
	err := dao.CaUsers.Ctx(ctx).Where("id = ?", userID).Scan(&userData)
	if err != nil {
		return nil, nil, gerror.Wrapf(err, "查询用户信息失败，userID: %d", userID)
	}

	// 查询用户权限信息
	var permissions []entity.CaPermissions
	if userID == 1 {
		err = dao.CaPermissions.Ctx(ctx).Where("1 = ? ", userID).Scan(&permissions)
	} else {
		err = dao.CaPermissions.Ctx(ctx).Where("creator_id = ?", userID).Scan(&permissions)
	}
	if err != nil {
		return nil, nil, gerror.Wrapf(err, "查询用户权限信息失败，userID: %d", userID)
	}
	// 转换为前端需要的结构体
	convertedPerms := convertPermissions(permissions)

	return &userData, convertedPerms, nil
}

// convertPermissions 将 entity.CaPermissions 转换为 v1.Permission
func convertPermissions(perms []entity.CaPermissions) []v1.Permission {
	var result []v1.Permission
	for _, perm := range perms {
		result = append(result, v1.Permission{
			ID:             int(perm.Id),
			ParentID:       perm.ParentId,
			PermissionName: perm.PermissionName,
			Route:          perm.Route,
			Icon:           perm.Icon,
			Module:         perm.Module,
			PermissionMark: perm.PermissionMark,
			Component:      perm.Component,
			Redirect:       &perm.Redirect, // 注意这里是指针类型
			Keepalive:      perm.Keepalive,
			IsInner:        true, // 存疑
			Sort:           perm.Sort,
			Type:           perm.Type,
			ActiveMenu:     perm.ActiveMenu,
			Hidden:         perm.Hidden == 2,
			CreatorID:      int(perm.CreatorId),
			CreatedAt:      strconv.Itoa(int(perm.CreatedAt)),
			UpdatedAt:      strconv.Itoa(int(perm.UpdatedAt)),
		})
	}
	return result
}

// UserOperateLogResult 定义包含日志列表和总数的结果结构体
type UserOperateLogResult struct {
	Logs  []v1.UserOperateLog
	Total int
}

// GetUserOperateLogs 获取用户操作日志列表
func GetUserOperateLogs(ctx context.Context, limit, page int, scope string, currentUserId int) (*UserOperateLogResult, error) {
	var logs []v1.UserOperateLog
	offset := (page - 1) * limit

	// 构建基础查询
	query := dao.CaLogOperate.Ctx(ctx)

	// 根据 scope 参数添加查询条件
	if scope == "self" {
		query = query.Where("creator_id", currentUserId)
	}

	// 复制查询用于统计总数
	countQuery := *query
	var total int
	_, err := countQuery.Count(&total)
	if err != nil {
		return nil, err
	}

	// 应用分页并查询日志列表
	query = query.Limit(limit).Offset(offset)
	err = query.Scan(&logs)
	if err != nil {
		return nil, err
	}

	result := &UserOperateLogResult{
		Logs:  logs,
		Total: total,
	}
	return result, nil
}

// UserLoginLogResult 定义包含登录日志列表和总数的结果结构体
type UserLoginLogResult struct {
	Logs  []v1.UserLoginLog
	Total int
}

// GetUserLoginLogs 获取用户登录日志列表
func GetUserLoginLogs(ctx context.Context, limit, page int) (*UserLoginLogResult, error) {
	var logs []v1.UserLoginLog
	offset := (page - 1) * limit

	// 构建基础查询
	query := dao.CaLogLogin.Ctx(ctx)

	// 复制查询用于统计总数
	countQuery := *query
	var total int
	_, err := countQuery.Count(&total)
	if err != nil {
		return nil, err
	}

	// 应用分页并查询登录日志列表
	query = query.Limit(limit).Offset(offset)
	err = query.Scan(&logs)
	if err != nil {
		return nil, err
	}

	result := &UserLoginLogResult{
		Logs:  logs,
		Total: total,
	}
	return result, nil
}

// GetCreatorByID 通过 creator_id 获取 creator 的 username
func GetCreatorByID(ctx context.Context, creatorID int) (string, error) {
	var user entity.CaUsers
	err := dao.CaUsers.Ctx(ctx).Where("id", creatorID).Fields("username").Scan(&user)
	if err != nil {
		return "", gerror.Wrapf(err, "查询 creator 的 username 失败，creator_id: %d", creatorID)
	}
	if user.Username == "" {
		return "", gerror.Newf("未找到 creator_id 为 %d 的用户信息", creatorID)
	}
	return user.Username, nil
}
